package com.atguigu.gulimail.product.service.impl;

import com.atguigu.gulimail.product.dao.CategoryBrandRelationDao;
import com.atguigu.gulimail.product.entity.AttrGroupEntity;
import com.atguigu.gulimail.product.vo.CategoryVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.gulimail.product.dao.CategoryDao;
import com.atguigu.gulimail.product.entity.CategoryEntity;
import com.atguigu.gulimail.product.service.CategoryService;
import org.springframework.transaction.annotation.Transactional;


@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {

    @Override
    public PageUtils queryPage(Map<String, Object> params) {

        final IPage<CategoryEntity> page1 = new Query<CategoryEntity>().getPage(params);
        final QueryWrapper<CategoryEntity> wrapper = new QueryWrapper<>();
        if (params.containsKey("key")) {
            final String key = (String) params.get("key");
            wrapper.like("name", key).or().eq("cat_id", key);
        }

        IPage<CategoryEntity> page = this.page(
                page1,
                wrapper
        );
        return new PageUtils(page);
    }

    @Override
    public List<CategoryVo> listWithTree() {
        final List<CategoryEntity> categoryEntities =
                baseMapper.selectList(null);
        final List<CategoryVo> rootEntities =
                categoryEntities.stream().filter(categoryEntity ->
                        categoryEntity.getParentCid() == 0)
                        .map(categoryEntity -> {
                            final CategoryVo categoryVo = new CategoryVo();
                            BeanUtils.copyProperties(categoryEntity, categoryVo);
                            return categoryVo;
                        }).collect(Collectors.toList());

        for (CategoryVo rootEntity : rootEntities) {
            assembleTree(categoryEntities, rootEntity);
        }
        categoryEntities.sort((o1, o2) -> {
            if (o1.getSort() == null) {
                o1.setSort(0);
            }
            if (o2.getSort() == null) {
                o2.setSort(0);
            }
            return o1.getSort() - o2.getSort();
        });
        return rootEntities;
    }
    @Autowired
    CategoryBrandRelationDao  categoryBrandRelationDao;

    @Override
    @Transactional
    public void update(CategoryEntity category) {
        this.updateById(category);
        categoryBrandRelationDao.update(category.getCatId(), category.getName());

    }

    private void assembleTree(List<CategoryEntity> categoryEntities,
                              CategoryVo rootEntity) {
        final List<CategoryVo> children =
                categoryEntities.stream().filter(categoryEntity ->
                        categoryEntity.getParentCid().equals(rootEntity.getCatId()))
                        .map(categoryEntity -> {
                            final CategoryVo categoryVo = new CategoryVo();
                            BeanUtils.copyProperties(categoryEntity, categoryVo);
                            assembleTree(categoryEntities, categoryVo);
                            return categoryVo;
                        }).sorted((o1, o2) -> {
                    if (o1.getSort() == null) {
                        o1.setSort(0);
                    }
                    if (o2.getSort() == null) {
                        o2.setSort(0);
                    }
                    return o1.getSort() - o2.getSort();
                }).collect(Collectors.toList());
        rootEntity.setChildren(children);
    }

    @Override
    public Long[] getCatelogPath(Long pCatelogId) {
        final List<Long> paths = new ArrayList<>();
        Long categoryId = pCatelogId;
        while (categoryId != null && categoryId > 0) {
            paths.add(categoryId);
            final CategoryEntity byId = getById(categoryId);
            categoryId = byId.getParentCid();
        }
        Collections.reverse(paths);
        return paths.toArray(new Long[0]);
    }

}